package com.wisdom.admin.service.impl;

import com.github.pagehelper.PageHelper;
import com.wisdom.admin.bo.AdminUserDetails;
import com.wisdom.admin.common.utils.JwtTokenUtil;
import com.wisdom.admin.dto.UmsAdminParam;
import com.wisdom.admin.dto.WxLoginParam;
import com.wisdom.admin.mbg.mapper.UmsAdminLoginLogMapper;
import com.wisdom.admin.mbg.mapper.UmsAdminMapper;
import com.wisdom.admin.mbg.model.UmsAdmin;
import com.wisdom.admin.mbg.model.UmsAdminExample;
import com.wisdom.admin.mbg.model.UmsAdminLoginLog;
import com.wisdom.admin.service.UmsAdminService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ming
 * @ClassName UmsAdminServiceImpl.java
 * @Description 用户服务端接口实现
 * @createTime 2021年03月13日 22:15:00
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Value("${jwt.expiration}")
    private String expiration;

    @Autowired(required = false)
    private UmsAdminMapper umsAdminMapper;

    @Autowired(required = false)
    private UmsAdminLoginLogMapper umsAdminLoginLogMapper;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public String login(String username, String password)
    {
        String token = null;
        UmsAdmin admin = getAdminByUsername(username);
        if (admin == null){
            return null;
        }

        if (!passwordEncoder.matches(password,admin.getPassword())){
            LOGGER.warn("用户:{}登录失败,密码错误",admin.getUsername());
            return null;
        }
        insertLoginLpg(admin);
        return jwtTokenUtil.generateToken(admin);
    }

    @Override
    public Map<String,String> wxlogin(WxLoginParam wxLoginParam) {
        Map<String,String> map = new HashMap<>();
        map.put("expire",expiration);
        //根据openId获取用户是否存在
        UmsAdmin user = getUserByOpenId(wxLoginParam.getOpenid());
        if (user != null){
            map.put("token",tokenHead+" "+jwtTokenUtil.generateToken(user));
            map.put("id",user.getId().toString());
            return map;
        }
        //不存在注册
        UmsAdminParam umsAdminParam = new UmsAdminParam();
        umsAdminParam.setType(5);
        umsAdminParam.setOpenid(wxLoginParam.getOpenid());
        Map userinfo = wxLoginParam.getUserinfo();
        umsAdminParam.setIcon(userinfo.get(new String("avatarUrl")).toString());
        umsAdminParam.setNickName(userinfo.get(new String("nickName")).toString());
        if (wxLoginParam.getUsername() == null){
            //生成统一的用户名
            String username = "csp1001";
            umsAdminParam.setUsername(username);
            umsAdminParam.setPassword("123456");
        }
        UmsAdmin register = register(umsAdminParam);
        if (register == null){
            return null;
        }
        map.put("token",tokenHead+" "+jwtTokenUtil.generateToken(register));
        map.put("id",register.getId().toString());
        return map;
    }

    @Override
    public UmsAdmin getAdminByUsername(String username)
    {
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<UmsAdmin> lists = umsAdminMapper.selectByExample(example);
        if (lists != null && lists.size() > 0){
            return lists.get(0);
        }
        return null;
    }

    @Override
    public UmsAdmin register(UmsAdminParam umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam,umsAdmin);
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setStatus(1);
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());
        List<UmsAdmin> lists = umsAdminMapper.selectByExample(example);
        if (lists.size() > 0){
            LOGGER.warn("用户注册失败,用户名:{}已存在",umsAdmin.getUsername());
            return null;
        }
        String password = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(password);
        umsAdminMapper.insert(umsAdmin);
        return umsAdmin;
    }

    /**
     * 写入登录记录
     * @param admin 用户信息
     */
    private void insertLoginLpg(UmsAdmin admin)
    {
        if (admin == null) return;
        UmsAdminLoginLog loginLog = new UmsAdminLoginLog();
        loginLog.setAdminId(admin.getId());
        loginLog.setCreateTime(new Date());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        loginLog.setIp(request.getRemoteAddr());
        umsAdminLoginLogMapper.insert(loginLog);
    }

    @Override
    public UserDetails loadUserByUsername(String username) {
        UmsAdmin admin = getAdminByUsername(username);
        if (admin != null){
            return new AdminUserDetails(admin);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

    /**
     * 更具openId获取用户
     * @param openId
     * @return
     */
    public UmsAdmin getUserByOpenId(String openId) {
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andOpenidEqualTo(openId);
        List<UmsAdmin> lists = umsAdminMapper.selectByExample(example);
        if (lists != null && lists.size() > 0){
            return lists.get(0);
        }
        return null;
    }



    @Override
    public List<UmsAdmin> getUserLists(String keyword, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        UmsAdminExample example = new UmsAdminExample();
        UmsAdminExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(keyword)){
            criteria.andUsernameLike("%"+keyword+"%");
            example.or(example.createCriteria().andNickNameLike("%"+keyword+"%"));
        }
        return umsAdminMapper.selectByExample(example);
    }
}
